<template>
    <div id="container">
    </div>
</template>

<script setup lang="ts">
import * as THREE from 'three'
import type { threeJsTest1 } from '@/interface/interface'
import { onBeforeUnmount, onMounted, onUnmounted } from 'vue';
import { destroy } from '@/utils/$Global';
import { createMultiMaterialObject } from 'three/examples/jsm/utils/SceneUtils.js';

let scene: { background: any; add: (arg0: any) => void; },
    camera: { position: { z: number; set: (arg0: number, arg1: number, arg2: number) => void; }; rotation: { order: string; }; },
    renderer: any,
    cube: { rotation: { x: number; y: number; }; },
    animationID: number

onMounted(() => {
    init()
})

const init = () => {
    let container = document.getElementById('container');
    // console.log('container', container)
    // 创建场景
    scene = new THREE.Scene();
    // 加背景色
    scene.background = new THREE.Color(0x9370DB)
    // 创建相机
    camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
    );
    // 设置照相机的位置
    camera.position.z = 5;
    // 创建渲染器，设置尺寸为窗口尺寸，并将渲染后的元素添加到body
    renderer = new THREE.WebGLRenderer({ antialias: true });// antialias:true 开启抗锯齿
    // 设置设备像素比。通常用于HiDPI设备防止模糊输出canvas
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(window.innerWidth, window.innerHeight);
    //@ts-ignore
    container.appendChild(renderer.domElement);

    // 创建一个Mesh（橘红（OrangeRed）色的3D立方体），并添加到场景中
    // 创建几何体模型（立方几何体）
    // let geometry = new THREE.BoxGeometry();
    // 创建圆环几何体模型
    // 环面半径为2，管道半径为1，管道横截面分段数为16，管道分段数为6
    let geometry = new THREE.TorusGeometry(2, 1, 16, 100);
    // 创建基础网格材质
    let materialBasic = new THREE.MeshBasicMaterial({
        color: 0xFF4500,
        wireframe: true   // 是否将几何体渲染为线框，默认值为false（即渲染为平面多边形）
    });
    // 创建法线网格材质
    let materialNormal = new THREE.MeshNormalMaterial();
    // 创建多种网格（因为有多个材质）
    // 第一个参数是几何模型，第二参数是材质
    cube = createMultiMaterialObject(geometry, [
        materialBasic,
        materialNormal
    ]);
    // cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    // 为了方便观察3D图像，添加三维坐标系对象
    // let axes = new THREE.AxesHelper(6);
    // scene.add(axes);

    animate();
}

// 浏览器每次渲染的时候更新立方体的旋转角度
const animate = () => {
    animationID = requestAnimationFrame(animate);

    cube.rotation.x += 0.001;
    cube.rotation.y += 0.001;
    console.log('cube')

    renderer.render(scene, camera);
};

onBeforeUnmount(() => {
    destroy(scene, renderer, animationID)
})

onUnmounted(() => {
    console.log('Cube组件卸载了')
})


// function createMultiMaterialObject (geometry: any, arg1: any[]): { rotation: { x: number; y: number; }; } {
//     throw new Error('Function not implemented.');
// }


// 墨卡托坐标转换函数
function mercatorProjection(latitude: number, longitude: number) {
    const earthRadius = 6378137;
    const x = longitude * (earthRadius * Math.PI / 180);
    const y = Math.log(Math.tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180);
    return { x, y };
}

// 射线检测函数
function rayIntersectsSegment(ray: THREE.Ray, segmentStart: { y: number; x: number; }, segmentEnd: { y: number; x: number; }) {
    const denominator = (ray.direction.x * (segmentEnd.y - segmentStart.y)) - (ray.direction.y * (segmentEnd.x - segmentStart.x));
    if (denominator === 0) return false; // Ray and segment are parallel

    const t = ((segmentEnd.x - segmentStart.x) * (ray.origin.y - segmentStart.y) - (segmentEnd.y - segmentStart.y) * (ray.origin.x - segmentStart.x)) / denominator;
    const u = ((ray.origin.x - segmentStart.x) * (segmentEnd.y - segmentStart.y) - (ray.origin.y - segmentStart.y) * (segmentEnd.x - segmentStart.x)) / denominator;

    // Check if the intersection point is on the line segment and the ray
    return (u >= 0 && u <= 1) && (t >= 0);
}

// 主要的检测函数
function isPointInsideShapes(point: { latitude: number; longitude: number; }, shapes: any) {
    // 将点转换为墨卡托坐标
    const mercatorPoint = mercatorProjection(point.latitude, point.longitude);

    // 创建射线，这里选择水平方向
    const ray = new THREE.Ray(new THREE.Vector3(mercatorPoint.x, mercatorPoint.y, 0), new THREE.Vector3(1, 0, 0));

    // 遍历所有形状
    for (const shape of shapes) {
        // 将形状的路径转换为线段数组
        const segments = [];
        let lastPoint = null;
        for (let i = 0; i < shape.vertices.length; i++) {
            const currentPoint = shape.vertices[i];
            if (lastPoint !== null) {
                segments.push([lastPoint, currentPoint]);
            }
            lastPoint = currentPoint;
        }
        segments.push([lastPoint, shape.vertices[0]]); // 闭合路径

        // 计算射线与线段的交点数量
        let intersections = 0;
        for (const [start, end] of segments) {
            if (rayIntersectsSegment(ray, start, end)) {
                intersections++;
            }
        }

        // 判断交点数量
        if (intersections % 2 === 1) {
            return true; // 点在至少一个形状内
        }
    }

    return false; // 点不在任何形状内
}
</script>



<style scoped lang="less">
.container {
    height: 600px
}
</style>